<template>
  <div :class="[{ fullscreen: isFullscreen}, 'box']" ref="box">
    <div class="content-box">
      <el-form :inline="true" :model="state.dataForm">
        <el-form-item>
          <!-- <el-select v-model="state.dataForm.area" :placeholder="$t('powerSupplyInfo.area')" clearable>
            <el-option :label="$t('powerSupplyInfo.area1')" :value="1"></el-option>
            <el-option :label="$t('powerSupplyInfo.area2')" :value="2"></el-option>
            <el-option :label="$t('powerSupplyInfo.area3')" :value="3"></el-option>
          </el-select> -->
          <ren-dept-tree style="width: 100%" v-model="state.dataForm.deptId" placeholder="选择路线"
            :query="true"></ren-dept-tree>
        </el-form-item>
        <!-- <el-form-item :label="$t('powerSupplyInfo.selectChannel')">
          <el-select v-model="state.dataForm.channel" :placeholder="$t('powerSupplyInfo.channel')" clearable>
            <el-option :label="$t('powerSupplyInfo.channel1')" :value="1"></el-option>
            <el-option :label="$t('powerSupplyInfo.channel2')" :value="2"></el-option>
            <el-option :label="$t('powerSupplyInfo.channel3')" :value="3"></el-option>
          </el-select>
        </el-form-item> -->
        <el-form-item>
          <p class="handel-p">
            <el-form-item>
              <el-button plain @click="state.getDataList()">{{ $t("query") }}</el-button>
            </el-form-item>
          </p>
        </el-form-item>
      </el-form>
      <canvas ref="myCanvas" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp"
        @mouseleave="onMouseLeave" @wheel="handleWheel"></canvas>
      <div class="function-btns">
        <img :src="isHoveringMagnify?magnifyHoverSrc:magnifySrc" @mouseover="isHoveringMagnify = true"
          @mouseleave="isHoveringMagnify = false" @click="magnifyOnClick" alt="放大" title="放大" />
        <img :src="isHoveringMinification ? minificationHoverSrc : minificationSrc" class="function-img-margin"
          @mouseover="isHoveringMinification = true" @mouseleave="isHoveringMinification = false"
          @click=" minificationOnClick" alt="缩小" title="缩小" />
        <img :src="isHoveringFullScreen ? fullScreenHoverSrc : fullScreenSrc" @mouseover="isHoveringFullScreen = true"
          @mouseleave="isHoveringFullScreen = false" @click="fullScreenOnClick" alt="全屏" title="全屏" />
      </div>
    </div>
  </div>

</template>

<script lang="ts" setup>
  import useView from "@/hooks/useView";
  import { reactive, toRefs, onMounted, ref, watch } from "vue";
  const view = reactive({
    getDataListURL: '/KxStation/kxstation/getNetList',
    dataForm: {
      deptId: ''
    }
  });
  const state = reactive({ ...useView(view), ...toRefs(view) });

  // 定义普通状态和悬停状态的图片路径
  const magnifySrc = new URL('./imgs/magnify.png', import.meta.url).href;
  const magnifyHoverSrc = new URL('./imgs/magnify-hover.png', import.meta.url).href;
  const minificationSrc = new URL('./imgs/minification.png', import.meta.url).href;
  const minificationHoverSrc = new URL('./imgs/minification-hover.png', import.meta.url).href;
  const fullScreenSrc = new URL('./imgs/fullScreen.png', import.meta.url).href;
  const fullScreenHoverSrc = new URL('./imgs/fullScreen-hover.png', import.meta.url).href;

  // 定义鼠标悬停状态
  const isHoveringMagnify = ref(false);
  const isHoveringMinification = ref(false);
  const isHoveringFullScreen = ref(false);
  const myCanvas = ref<HTMLCanvasElement | null>(null);
  const box = ref<HTMLDivElement | null>(null);
  // 标记是否处于全屏状态
  let isFullscreen = ref(false);
  // 初始缩放比例
  const scaleValue = ref(1);
  // 目标缩放比例
  const targetScale = ref(1);
  // 最小缩放比例
  const MIN_SCALE = 0.5;
  // 最大缩放比例
  const MAX_SCALE = 3;
  // 动画持续时间（毫秒）
  const ANIMATION_DURATION = 200;
  // 每帧的时间间隔（毫秒）
  const ANIMATION_STEP = 10;
  let animationFrameId : number | null = null;

  // canvas鼠标拖动参数
  let isDragging = false; // 是否正在拖动
  let lastX = 0; // 上一次鼠标按下时的 x 坐标
  let lastY = 0; // 上一次鼠标按下时的 y 坐标
  const offsetX = ref(0); // 水平偏移量
  const offsetY = ref(0); // 垂直偏移量


  // 定义电箱下面竖线长度
  let verticalHeight = 100;
  // 定义电箱的宽高
  let electricBoxWidth = 110;
  let electricBoxHeight = 140;
  // 定义主机1的宽高
  let hostOneWidth = 130;
  let hostOneHeight = 180;
  // 定义主机2线条往上的汇聚点的高度
  let convergePointOffsetY = 300;
  // 每组主机2宽度、间隔
  let hostTwoWidth = 80;
  let hostTwoHeight = 120;
  let spacing = 30;
  //smallList和bigList小组之间的间距
  let subgroupSpacing = 50;
  // 每组主机2之间的水平间距
  let groupSpacing = 100; // 每组主机2之间的固定间隔

  // 大电塔与汇聚点之间的空隙
  let gapAboveLargeTower = 30;
  // 汇聚点的中心x坐标
  let convergenceX = 0;

  // 记录每个矩形的边缘居中坐标
  const bigListRightCenters : object[] = []; // 存储每个 bigList 矩形的右侧边缘居中坐标
  const smallListLeftCenters : object[] = []; // 存储每个 smallList 矩形的左侧边缘居中坐标

  // 定义线条颜色
  const lineColor = '#00C4FF';


  const updateScale = (newScale, mouseX = 0, mouseY = 0) => {
    console.log(newScale);
    if (newScale < MIN_SCALE || newScale > MAX_SCALE) return;

    const zoomFactor = newScale / scaleValue.value;

    // 更新缩放比例
    scaleValue.value = newScale;

    // 计算新的平移原点，确保缩放以鼠标位置为中心
    offsetX.value = mouseX - (mouseX - offsetX.value) * zoomFactor;
    offsetY.value = mouseY - (mouseY - offsetY.value) * zoomFactor;

    // 重绘画布
    initializeCanvas();
  };

  /**
   * 放大按钮点击事件
   */
  const magnifyOnClick = () => {
    const newScale = Math.min(scaleValue.value + 0.2, MAX_SCALE);
    updateScale(newScale);
  };

  /**
   * 缩小按钮点击事件
   */
  const minificationOnClick = () => {
    const newScale = Math.max(scaleValue.value - 0.2, MIN_SCALE);
    updateScale(newScale);
  };

  /**
   * 鼠标滚轮放大缩小事件
   * @param {WheelEvent} event - 滚轮事件
   */
  const handleWheel = (event : any) => {
    event.preventDefault();

    // 获取鼠标在画布上的位置
    const rect = myCanvas.value.getBoundingClientRect();
    console.log(rect);
    const mouseX = event.clientX - rect.left;
    const mouseY = event.clientY - rect.top;
    // 根据滚轮方向调整缩放比例
    const step = 0.2; // 统一缩放步长
    const newScale = event.deltaY > 0
      ? Math.max(scaleValue.value - step, MIN_SCALE) // 缩小
      : Math.min(scaleValue.value + step, MAX_SCALE); // 放大

    updateScale(newScale, mouseX, mouseY);
  };

  // 全屏按钮点击
  const fullScreenOnClick = () => {
    isFullscreen.value = !isFullscreen.value;
  }

  // 鼠标按下事件
  const onMouseDown = (e : any) => {
    isDragging = true;
    lastX = e.offsetX - offsetX.value; // 记录鼠标按下时的相对位置
    lastY = e.offsetY - offsetY.value;
  };

  // 鼠标移动事件
  const onMouseMove = (e : any) => {
    if (!isDragging) return;

    // 更新偏移量
    offsetX.value = e.offsetX - lastX;
    offsetY.value = e.offsetY - lastY;

    // 重新绘制画布内容
    initializeCanvas();
  };

  // 鼠标松开事件
  const onMouseUp = () => {
    isDragging = false;
  };

  // 鼠标离开画布事件
  const onMouseLeave = () => {
    isDragging = false;
  };



  // canvas创建
  const initializeCanvas = () => {
    if (!myCanvas.value) return;
    const canvas = myCanvas.value;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    // 接口数据
    // const data : any = state.dataList;

    const data = [
      {
        id: "1859840279086854145",
        name: "电塔205",
        deptId: "1856626876524822530",
        substationName: "洛西变电站",
        smallList: [
          { id: "1859840358854127617", name: "小电塔205-1" },
          { id: "1859840464814829570", name: "小电塔205-2" },
        ],
        bigList: [
          { id: "1859840536977829890", name: "大电塔205-1" },
          { id: "1859841129297440770", name: "大电塔205-2" },
          { id: "1859841222733950978", name: "大电塔205-3" },
          { id: "1859841294544629760", name: "大电塔205-4" },
        ],
      },
      {
        id: "1859841505975300098",
        name: "电塔204",
        deptId: "1856626876524822530",
        substationName: null,
        smallList: [
          { id: "1859840536977829890", name: "大电塔205-1" },
          { id: "1859840536977829890", name: "大电塔205-1" },
        ],
        bigList: [
          { id: "1859841673747460097", name: "大电塔204-1" },
          { id: "1859841818333507586", name: "大电塔204-2" },
        ],
      }, {
        id: "1859841505975300098",
        name: "电塔203",
        deptId: "1856626876524822530",
        substationName: null,
        smallList: [
          { id: "1859841612300906498", name: "小电塔A-1" },
        ],
        bigList: [
          { id: "1859841673747460097", name: "大电塔204-1" },
          { id: "1859841818333507586", name: "大电塔204-2" },
        ],
      }
    ];
    // 动态获取画布的实际宽高（由 CSS 决定）
    const canvasWidth = canvas.clientWidth;
    const canvasHeight = canvas.clientHeight;
    // 设置画布大小
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    // 清除画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 如果没有数据不绘制
    if (!data || data.length == 0) return
    // canvas宽高低于1800*750
    if (canvas.width < 1800 && canvas.height < 750) {
      // 定义电箱下面竖线长度
      verticalHeight = 100 - 50;
      // 定义电箱的宽高
      electricBoxWidth = 110 - 30;
      electricBoxHeight = 140 - 50;

      // 定义主机1的宽高
      hostOneWidth = 130 - 50;
      hostOneHeight = 180 - 70;
      // 定义主机2线条往上的汇聚点的高度
      convergePointOffsetY = 300 - 220;
      // 每组主机2宽度、间隔
      hostTwoWidth = 80 - 20;
      hostTwoHeight = 120 - 30;
      spacing = 30;
      //smallList和bigList小组之间的间距
      subgroupSpacing = 50 + 20;
      // 每组主机2之间的水平间距
      groupSpacing = 100; // 每组主机2之间的固定间隔
      // 大电塔与汇聚点之间的空隙
      gapAboveLargeTower = 30;
    }

    // 偏移量
    ctx.translate(offsetX.value, offsetY.value);
    ctx.scale(scaleValue.value, scaleValue.value); // 应用缩放比例
    // 起始位置：左下角距离左边 50px，距离底部 60px
    let currentX = 50;
    let startY = canvas.height - 60;
    ctx.save(); // 保存当前绘图状态
    // 加载图片
    const loadImage = (src : string) : Promise<HTMLImageElement> => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = src;
        img.onload = () => resolve(img);
        img.onerror = () => reject(new Error(`无法加载图片: ${src}`));
      });
    };
    const drawImagesAndLines = async () => {
      try {
        // 导入本地图片
        const hostComputerTwoSrc = new URL('./imgs/hostComputer2.png', import.meta.url).href;
        const hostComputerOneSrc = new URL('./imgs/hostComputer1.png', import.meta.url).href;
        const electricBoxSrc = new URL('./imgs/electricBox.png', import.meta.url).href;
        const rectangleSrc = new URL('./imgs/rectangle.png', import.meta.url).href;
        const textBgSrc = new URL('./imgs/textBg.png', import.meta.url).href;
        const blockSrc = new URL('./imgs/block.png', import.meta.url).href;
        const hostComputerTwoImage = await loadImage(hostComputerTwoSrc);
        const hostComputerOneImage = await loadImage(hostComputerOneSrc);
        const electricBoxImage = await loadImage(electricBoxSrc);
        const rectangleImage = await loadImage(rectangleSrc);
        const textBgImage = await loadImage(textBgSrc);
        const blockImage = await loadImage(blockSrc);

        // 绘制主机2的通用函数
        const drawTowerGroup = (ctx : any, hosts : Object[], currentX : number, startY : number, type : string) => {
          // 绘制主机2
          hosts.forEach((hostItem, index) => {
            const hostX = currentX + index * (hostTwoWidth + spacing);
            const hostY = startY - hostTwoHeight;
            // 绘制图片
            ctx.drawImage(hostComputerTwoImage, hostX, hostY, hostTwoWidth, hostTwoHeight);

            // 创建渐变色
            let gradient = ctx.createLinearGradient(
              hostX, hostY,
              hostX, hostY + hostTwoHeight
            );
            gradient.addColorStop(0, "#00C4FF"); // 起始颜色
            gradient.addColorStop(0.5, "#00e6ff"); // 起始颜色
            gradient.addColorStop(1, "#FFFFFF"); // 结束颜色
            ctx.fillStyle = gradient;
            // 主机2上方文字内容
            const mbpsText = `##Mbps`;
            // 测量文字的宽度和高度
            ctx.font = '12px Arial';
            const mbpsTextMetrics = ctx.measureText(mbpsText);
            const mbpsTextWidth = mbpsTextMetrics.width;
            const mbpsTextHeight = 12; // 假设字体高度为 12px

            // 矩形的宽高（加上内边距 10px）
            const rectPadding = 10;
            const rectWidth = mbpsTextWidth + 2 * rectPadding;
            const rectHeight = mbpsTextHeight + 2 * rectPadding;

            // 绘制矩形背景
            ctx.drawImage(rectangleImage,
              hostX + (hostTwoWidth - rectWidth) / 2 + 5, // 矩形水平居中
              hostY - rectHeight - 10, // 矩形位于电塔上方 10px
              rectWidth,
              rectHeight
            );

            // 在矩形中绘制文字
            ctx.fillText(
              mbpsText,
              hostX + hostTwoWidth / 2 - rectWidth / 2 + 15, // 文字水平居中
              hostY - 10 - rectHeight / 2 + mbpsTextHeight / 2 // 文字垂直居中
            );

            // 创建主机2下方
            const hostText = hostItem.name;
            ctx.font = '12px Arial';
            // bug ？？？字体颜色为什么不是渐变
            ctx.fillStyle = '#fff';
            const hostTextWidth = ctx.measureText(hostText).width;
            const hostTextX = hostX + hostTwoWidth / 2 - hostTextWidth / 2 - 10; // 文字水平居中
            const hostTextY = hostY + hostTwoHeight + 20; // 在图片下方20px处
            ctx.fillText(hostText, hostTextX, hostTextY);

            // 创建dbm文字
            const dbmText = '##dbm';
            ctx.font = '12px Arial';
            ctx.fillStyle = '#fff';
            const dbmTextWidth = ctx.measureText(dbmText).width;
            const dbmTextX = hostX + hostTwoWidth / 2 - dbmTextWidth / 2 - 10; // 文字水平居中
            const dbmTextY = hostTextY + 20; // 在图片下方40px处
            ctx.fillText(dbmText, dbmTextX, dbmTextY);
          });
        };

        // 绘制汇聚点通用函数
        const drawConvergencePoint = (ctx : any, currentX : any, startY : any, groupWidth : any, hostCount : any, isSmallList : boolean, tower : any) => {

          // 计算汇聚点的中心 X 坐标
          convergenceX = currentX + groupWidth / 2 + 10;

          // 计算汇聚点的 Y 坐标（矩形上方 20px 再往上 300px）
          const convergenceY = startY - hostTwoHeight - convergePointOffsetY - 10 - 20;

          // 在汇聚点上方 6px 的位置绘制一个 55*20 的矩形
          const rectWidth = 55;
          const rectHeight = 20;
          const rectX = convergenceX - rectWidth / 2; // 矩形左上角的 X 坐标（水平居中）
          const rectY = convergenceY - 6 - rectHeight; // 矩形左上角的 Y 坐标（汇聚点上方 6px）

          // 创建线性渐变色
          const gradient = ctx.createLinearGradient(
            rectX, rectY,
            rectX + rectWidth, rectY + rectHeight
          );
          gradient.addColorStop(0, "#028EBC"); // 起始颜色
          gradient.addColorStop(1, "#FFFFFF"); // 结束颜色
          // 绘制矩形边框
          ctx.strokeStyle = gradient; // 设置边框颜色为渐变色
          ctx.lineWidth = 1; // 边框宽度为 1px
          ctx.strokeRect(rectX, rectY, rectWidth, rectHeight); // 绘制矩形边框
          // 根据数据来源设置文字内容
          const text = isSmallList ? "小号侧" : "大号侧";
          // 设置文字样式
          ctx.font = "10px Arial"; // 字体大小和字体
          ctx.fillStyle = "#fff"; // 文字颜色
          // 测量文字的宽度和高度
          const textMetrics = ctx.measureText(text);
          const textWidth = textMetrics.width;
          const textHeight = 10; // 假设字体高度为 10px
          // 定义小矩形的尺寸
          const smallRectWidth = 12;
          const smallRectHeight = 12;
          // 计算整体宽度和高度
          const totalWidth = textWidth + 3 + smallRectWidth; // 文字宽度 + 间隙 + 小矩形宽度
          const totalHeight = Math.max(textHeight, smallRectHeight); // 取文字高度和小矩形高度的最大值
          // 计算整体的水平和垂直居中位置
          const centerX = rectX + (rectWidth - totalWidth) / 2; // 整体水平居中
          const centerY = rectY + (rectHeight - totalHeight) / 2 + textHeight; // 整体垂直居中（考虑基线偏移）
          // 计算小矩形的位置
          const smallRectX = centerX; // 小矩形的 X 坐标（最左边）
          const smallRectY = centerY - textHeight + (textHeight - smallRectHeight) / 2 + 1; // 小矩形的 Y 坐标（垂直居中）

          // 绘制小矩形
          ctx.drawImage(blockImage, smallRectX, smallRectY, smallRectWidth, smallRectHeight);
          // 绘制文字
          const textX = smallRectX + smallRectWidth + 3; // 文字的起始 X 坐标（小矩形右侧 + 3px 间隙）
          const textY = centerY; // 文字的基线 Y 坐标
          ctx.fillText(text, textX, textY);

          // 计算主机1的位置，在每个“大号侧/小号侧”上方 8px 处绘制一个主机1
          const hostOneX = convergenceX - hostOneWidth / 2; // 水平居中
          const hostOneY = rectY - 8 - hostOneHeight; // 上方 8px

          ctx.drawImage(hostComputerOneImage, hostOneX, hostOneY, hostOneWidth, hostOneHeight); // 绘制主机1

          // 在主机1的上方再绘制同样的文字、55*20 的矩形和 12x12 的小矩形
          const upperRectY = hostOneY - 6 - rectHeight; // 上方 6px 的位置
          const upperRectX = convergenceX - rectWidth / 2; // 水平居中

          // 绘制上方的 55*20 矩形
          ctx.strokeStyle = gradient; // 使用相同的渐变色
          ctx.lineWidth = 1;
          ctx.strokeRect(upperRectX, upperRectY, rectWidth, rectHeight); // 绘制矩形边框

          // 计算上方小矩形和文字的位置
          const upperCenterX = upperRectX + (rectWidth - totalWidth) / 2; // 水平居中
          const upperCenterY = upperRectY + (rectHeight - totalHeight) / 2 + textHeight; // 垂直居中

          // 计算上方小矩形的位置
          const upperSmallRectX = upperCenterX; // 小矩形的 X 坐标（最左边）
          const upperSmallRectY = upperCenterY - textHeight + (textHeight - smallRectHeight) / 2; // 小矩形的 Y 坐标（垂直居中）

          // 绘制上方小矩形
          ctx.drawImage(blockImage, upperSmallRectX, upperSmallRectY, smallRectWidth, smallRectHeight);
          // 计算上方文字的位置
          const upperTextX = upperSmallRectX + smallRectWidth + 3; // 文字的起始 X 坐标（小矩形右侧 + 3px 间隙）
          const upperTextY = upperCenterY; // 文字的基线 Y 坐标
          // 绘制上方文字
          ctx.fillText(text, upperTextX, upperTextY);

          // 设置字体样式
          ctx.font = "10px Arial";
          ctx.fillStyle = "#BDE6E7";
          // 上部分文字
          const textTop = `${tower.name}汇聚`;
          const textBottom = `${isSmallList ? '小号侧' : '大号侧'}主机`;
          // 测量文字宽度
          const topMetrics = ctx.measureText(textTop);
          const bottomMetrics = ctx.measureText(textBottom);

          // 动态计算矩形的宽高
          const maxWidth = Math.max(topMetrics.width, bottomMetrics.width); // 最大宽度
          const fontHeight = parseInt(ctx.font); // 字体高度
          const verticalPadding = 5; // 上下内边距
          const textRectWidth = maxWidth + 2 * 10; // 矩形宽度（加上左右内边距）
          const textRectHeight = 2 * fontHeight + 3 * 10; // 矩形高度（两行文字 + 上下内边距）

          // 确定矩形的位置
          const labelDistance = 10; // 标签距离主机1的距离
          const labelX = isSmallList
            ? hostOneX - labelDistance - textRectWidth // 左侧标签
            : hostOneX + hostOneWidth + labelDistance; // 右侧标签
          const labelY = hostOneY + (hostOneHeight - textRectHeight) / 2; // 垂直居中对齐
          // 绘制矩形背景图边框
          ctx.drawImage(rectangleImage, labelX, labelY, textRectWidth, textRectHeight);
          // 绘制上面的文字
          const topTextX = labelX + (textRectWidth - topMetrics.width) / 2; // 水平居中
          const topTextY = labelY + 10 + fontHeight; // 第一行文字基线位置
          ctx.fillText(textTop, topTextX, topTextY);

          // 绘制下面的文字
          const bottomTextX = labelX + (textRectWidth - bottomMetrics.width) / 2; // 水平居中
          const bottomTextY = topTextY + fontHeight + verticalPadding; // 第二行文字基线位置
          ctx.fillText(textBottom, bottomTextX, bottomTextY);


          // 连接汇聚点的线条
          for (let i = 0; i < hostCount; i++) {
            const hostX = currentX + i * (hostTwoWidth + spacing) + hostTwoWidth / 2 + 10;
            const hostY = startY - hostTwoHeight - 10 - 40; // 矩形的顶部 Y 坐标
            // 绘制线条连接汇聚点
            ctx.beginPath();
            ctx.moveTo(convergenceX, convergenceY);
            ctx.lineTo(hostX, hostY);
            ctx.strokeStyle = lineColor; // 线条颜色
            ctx.lineWidth = 1;
            ctx.stroke();
            ctx.closePath();
          }
          // 主机1上方矩形的右侧边缘居中坐标
          const rightEdgeCenterX = upperRectX + rectWidth; // 右侧边缘 X 坐标
          const rightEdgeCenterY = upperRectY + rectHeight / 2; // 垂直居中 Y 坐标

          // 主机1上方矩形的左侧边缘居中坐标
          const leftEdgeCenterX = upperRectX; // 左侧边缘 X 坐标
          const leftEdgeCenterY = upperRectY + rectHeight / 2; // 垂直居中 Y 坐标

          // 如果 substationName 不为 null，则在上方边缘中心绘制一条 50px 的直线
          if (!isSmallList && tower.substationName !== null) {
            // 计算直线的起点和终点
            const startX = upperRectX + rectWidth / 2; // 矩形顶部中心点 X 坐标
            const startY = upperRectY;                 // 矩形顶部 Y 坐标
            const endX = startX;                       // 直线终点 X 坐标
            const endY1 = startY - 25;                     // 向上 50px 的终点 Y 坐标

            // 使用绘图上下文绘制直线
            ctx.beginPath();
            ctx.moveTo(startX, startY); // 起点
            ctx.lineTo(endX, endY1);     // 终点
            ctx.strokeStyle = lineColor;  // 设置线条颜色
            ctx.lineWidth = 1;          // 设置线条宽度
            ctx.stroke();               // 绘制线条

            // 文字内容和字体设置
            const text = '点对点至变电站';
            ctx.font = `10px Arial`; // 设置字体

            // 动态计算文字的宽度和高度
            const textMetrics = ctx.measureText(text);
            const textWidth = textMetrics.width; 		// 文字宽度
            const textHeight = parseInt(ctx.font);  // 文字高度

            // 计算文字的位置
            const textX = startX - textWidth / 2; // 水平居中：起点向左偏移文字宽度的一半
            const textY = endY1;  // Y 对齐到文字的顶部

            // 绘制文字
            ctx.fillStyle = '#fff';              // 设置文字颜色
            ctx.fillText(text, textX, textY);     // 绘制文字

            // 计算第二条直线的起点和终点
            const startTextY = textY - textHeight; // 文字顶部 Y 坐标
            const endY2 = startTextY - 35;             // 第二条直线终点 Y 坐标

            // 绘制第二条直线
            ctx.beginPath();
            ctx.moveTo(startX, startTextY); // 起点
            ctx.lineTo(startX, endY2);      // 终点
            ctx.strokeStyle = lineColor;      // 设置线条颜色
            ctx.lineWidth = 1;              // 设置线条宽度
            ctx.stroke();                   // 绘制线条

            // 电箱的左上角坐标
            const electricX = startX - electricBoxWidth / 2; // 矩形水平居中
            const electricY = endY2 - electricBoxHeight;     // 矩形顶部与第二条直线终点对齐
            // 绘制电箱
            ctx.drawImage(electricBoxImage, electricX, electricY, electricBoxWidth, electricBoxHeight);

            // 添加文字
            const electricText = tower.substationName;
            ctx.font = '12px Arial'; // 设置字体

            // 测量每行文字的宽度
            const electricTextWidth = ctx.measureText(electricText);

            // 动态设置矩形的宽度和高度
            const paddingX = 20; // 水平方向的额外空间
            const paddingY = 20; // 垂直方向的额外空间
            const lineHeight = parseInt(ctx.font); // 行高（可以根据字体大小调整）

            const rectangleWidth = electricTextWidth.width + paddingX; // 矩形宽度 = 最大文字宽度 + 额外空间
            const rectangleHeight = lineHeight + paddingY; // 矩形高度

            // 计算电信右侧矩形位置
            const rectangleX = electricX + electricBoxWidth + 22; // 矩形左上角 x 坐标
            // 计算电箱的中心 y 坐标
            const electricBoxCenterY = electricY + electricBoxHeight / 2;

            // 计算矩形的左上角 y 坐标，使矩形的中心点与电箱的中心点对齐
            const rectangleY = electricBoxCenterY - rectangleHeight / 2;

            // 绘制矩形
            ctx.drawImage(rectangleImage, rectangleX, rectangleY, rectangleWidth, rectangleHeight);

            // 计算文字位置
            const electricTextX = rectangleX + rectangleWidth / 2; // 文字水平居中
            const electricTextY = rectangleY + rectangleHeight / 2 + 1; // 文字垂直居中（有点偏差)

            // 创建线性渐变
            const gradient = ctx.createLinearGradient(
              electricTextX - rectangleWidth / 2, // 起点 x 坐标（矩形左侧）
              rectangleY,                 // 起点 y 坐标（矩形顶部）
              electricTextX - rectangleWidth / 2, // 终点 x 坐标（保持不变，实现垂直渐变）
              rectangleY + rectangleHeight     // 终点 y 坐标（矩形底部）
            );
            // background: linear-gradient(0deg, #00C4FF 0%, #FFFFFF 100%);
            // 添加渐变颜色
            gradient.addColorStop(0, '#00C4FF');   // 起点颜色
            gradient.addColorStop(1, '#ffffff');  // 终点颜色
            // 应用渐变到文字
            ctx.fillStyle = gradient; // 设置文字填充样式为渐变
            ctx.textAlign = 'center'; // 水平居中对齐
            ctx.textBaseline = 'middle'; // 垂直居中对齐

            // 绘制文字
            ctx.fillText(electricText, electricTextX, electricTextY);
            // 恢复绘图上下文状态（包括lineDash设置）
            ctx.restore();
          }
          // 返回主机1和上方矩形的坐标信息
          return {
            hostOneX,
            hostOneY,
            rightEdgeCenter: { x: rightEdgeCenterX, y: rightEdgeCenterY },
            leftEdgeCenter: { x: leftEdgeCenterX, y: leftEdgeCenterY }
          };
        };

        // // 绘制前一个大号侧与下一个小号侧相连的线
        // const drawConnectingLines = (ctx : any, bigListCenters : any, smallListCenters : any) => {

        // 	ctx.strokeStyle = lineColor; // 设置线条颜色
        // 	ctx.lineWidth = 1; // 设置线条宽度

        // 	for (let i = 0; i < bigListCenters.length - 1; i++) {
        // 		const startX = bigListCenters[i].x; // 当前 bigList 矩形的中心点 X 坐标
        // 		const startY = bigListCenters[i].y; // 当前 bigList 矩形的中心点 Y 坐标
        // 		const endX = smallListCenters[i + 1].x; // 下一个 smallList 矩形的中心点 X 坐标
        // 		const endY = smallListCenters[i + 1].y; // 下一个 smallList 矩形的中心点 Y 坐标

        // 		// 绘制直线
        // 		ctx.beginPath();
        // 		ctx.moveTo(startX, startY);
        // 		ctx.lineTo(endX, endY);
        // 		ctx.stroke();

        // 	}

        // };



        data.forEach((tower) => {
          // 绘制 smallList 主机2
          const smallListTowers = tower.smallList.map((item : any) => ({ ...item, type: "smallList" }));
          let smallListWidth = smallListTowers.length * (hostTwoWidth + spacing) - spacing;

          // 绘制 bigList 主机2
          const bigListTowers = tower.bigList.map((item : any) => ({ ...item, type: "bigList" }));
          let bigListWidth = bigListTowers.length * (hostTwoWidth + spacing) - spacing;

          // 绘制 smallList 主机2
          drawTowerGroup(ctx, smallListTowers, currentX, startY, "smallList");
          // 绘制 smallList 的汇聚点 、大号侧、小号侧、主机1
          let smallHostPosition = drawConvergencePoint(ctx, currentX, startY, smallListWidth, smallListTowers.length, true, tower);

          smallListLeftCenters.push(smallHostPosition.leftEdgeCenter); // 记录 smallList 矩形的左侧边缘居中坐标

          // 更新 X 坐标，跳过 smallList 主机2和子组间距
          currentX += smallListWidth + subgroupSpacing;

          // 绘制 bigList 主机2
          drawTowerGroup(ctx, bigListTowers, currentX, startY, "bigList");
          // 绘制 bigList 的汇聚点、大号侧、小号侧、主机1
          let bigHostPosition = drawConvergencePoint(ctx, currentX, startY, bigListWidth, bigListTowers.length, false, tower);

          bigListRightCenters.push(bigHostPosition.rightEdgeCenter); // 记录 bigList 矩形的右侧边缘居中坐标

          // 更新当前 X 坐标，为下一组主机2预留空间
          currentX += bigListWidth + groupSpacing + (bigListTowers.length < 4 ? 100 : -40);

          // 计算矩形的起始和结束位置
          const rectHeight = 50; // 矩形的高度固定为 50
          const startRectX = smallHostPosition.hostOneX + hostOneWidth; // 小号侧主机1的右边边缘
          const endRectX = bigHostPosition.hostOneX; // 大号侧主机1的左边边缘
          const rectWidth = endRectX - startRectX; // 矩形的宽度（通过计算得出）

          // 矩形的垂直居中位置
          const textBgImageStartY = smallHostPosition.hostOneY + (hostOneHeight - rectHeight) / 2; // 矩形顶部 Y 坐标
          const textBgImageEndY = textBgImageStartY + rectHeight; // 矩形底部 Y 坐标
          // 绘制主机1之间的背景图
          ctx.drawImage(textBgImage, startRectX, textBgImageStartY, rectWidth, rectHeight);

          // 在矩形居中位置绘制文字tower.name
          const text = tower.name;
          ctx.font = "12px Arial"; // 设置字体样式
          ctx.fillStyle = lineColor; // 设置文字颜色

          // 动态计算文字的宽度和高度
          const metrics = ctx.measureText(text); // 获取文字的测量信息
          const textWidth = metrics.width; // 文字的宽度
          const fontHeight = parseInt(ctx.font); // 从字体样式中提取字体高度（单位：像素）

          // 手动计算文字的左上角位置，使其居中
          const textX = startRectX + (rectWidth - textWidth) / 2; // 文字的 X 坐标
          const textY = textBgImageStartY + (rectHeight - fontHeight) / 2 + fontHeight; // 文字的 Y 坐标

          // 绘制文字
          ctx.fillText(text, textX, textY);

          // 在矩形上方5px处绘制文字“点对点终端”
          const topText = "点对点终端";
          ctx.font = "10px Arial"; // 设置字体样式
          ctx.fillStyle = "#fff"; // 设置文字颜色

          // 动态计算文字的宽度和高度
          const topMetrics = ctx.measureText(topText); // 获取文字的测量信息
          const topTextWidth = topMetrics.width; // 文字的宽度
          const topFontHeight = parseInt(ctx.font); // 从字体样式中提取字体高度（单位：像素）

          // 手动计算文字的左上角位置，使其水平居中，距离矩形上方5px
          const topTextX = startRectX + (rectWidth - topTextWidth) / 2; // 文字的 X 坐标
          const topTextY = textBgImageStartY - 5 - topFontHeight / 2; // 文字的 Y 坐标（文字基线位置）

          // 绘制文字“点对点终端”
          ctx.fillText(topText, topTextX, topTextY);

          // 在矩形下方5px处绘制文字“点对多点汇聚终端”
          const bottomText = "点对多点汇聚终端";
          ctx.font = "10px Arial"; // 设置字体样式
          ctx.fillStyle = "#d8d8d8"; // 设置文字颜色

          // 动态计算文字的宽度和高度
          const bottomMetrics = ctx.measureText(bottomText); // 获取文字的测量信息
          const bottomTextWidth = bottomMetrics.width; // 文字的宽度
          const bottomFontHeight = parseInt(ctx.font); // 从字体样式中提取字体高度（单位：像素）

          // 手动计算文字的左上角位置，使其水平居中，距离矩形下方5px
          const bottomTextX = startRectX + (rectWidth - bottomTextWidth) / 2; // 文字的 X 坐标
          const bottomTextY = textBgImageEndY + 5 + bottomFontHeight; // 文字的 Y 坐标（文字基线位置）

          // 绘制文字“点对多点汇聚终端”
          ctx.fillText(bottomText, bottomTextX, bottomTextY);

        })

        // 调用 drawConnectingLines 绘制连接线
        // drawConnectingLines(ctx, bigListRightCenters, smallListLeftCenters);
        // 绘制前一个大号侧与下一个小号侧相连的线

        ctx.save()
        ctx.strokeStyle = lineColor; // 设置线条颜色
        ctx.lineWidth = 1; // 设置线条宽度

        for (let i = 0; i < bigListRightCenters.length - 1; i++) {
          const startX = bigListRightCenters[i].x; // 当前 bigList 矩形的中心点 X 坐标
          const startY = bigListRightCenters[i].y; // 当前 bigList 矩形的中心点 Y 坐标
          const endX = smallListLeftCenters[i + 1].x; // 下一个 smallList 矩形的中心点 X 坐标
          const endY = smallListLeftCenters[i + 1].y; // 下一个 smallList 矩形的中心点 Y 坐标
          // 绘制直线
          ctx.beginPath();
          ctx.moveTo(startX, startY);
          ctx.lineTo(endX, endY);
          ctx.stroke();
        }

      } catch (error) {
        console.error('图片加载失败:', error);
      } finally {
        ctx.restore(); // 恢复绘图状态
      }
    };
    // 调用绘制函数
    drawImagesAndLines();
  };
  // 监听数据变化
  watch(() => state.dataList, (newDataList) => {
    if (newDataList && newDataList.length > 0) {
      initializeCanvas();
    }

  },
    { immediate: false } // 立即监听一次初始值
  );

  onMounted(() => {


  });
</script>

<style lang="scss" scoped>
  .box {
    display: flex;
    padding: 40px 10px 20px 10px;
    position: relative;
    transition: all 0.2s ease;


    .content-box {
      flex: 1;
      height: calc(100vh - 60px - 40px - 10px);
      padding: 20px;
      background-image: url("./imgs/content_bg.png");
      background-size: 100% 100%;
      color: #FFFFFF;
      overflow-y: auto;
      position: relative;

      .el-form {
        margin: 8px 0 0 8px;
      }
    }

    canvas {
      width: 100%;
      // height: calc(92vh - 40px - 50px - 12px);
      height: 90%;
      background-color: transparent;
      cursor: grab;
    }

    .function-btns {
      position: absolute;
      right: 28px;
      top: 115px;
      z-index: 1;
      display: flex;
      flex-direction: column;

      img {
        cursor: pointer;
        display: inline-block;
        transition: transform 0.1s ease, box-shadow 0.1s ease;
        /* 添加过渡效果 */
      }

      img:active {
        transform: scale(0.9);
        box-shadow: inset 0px 2px 5px rgba(0, 0, 0, 0.2);
        /* 内阴影效果 */
      }

      .function-img-margin {
        margin: 10px 0;
      }
    }
  }

  /* 全屏样式 */
  .box.fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    padding: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1;
    background-color: lightblue;

    .content-box {
      height: 100vh;

    }

    canvas {
      height: calc(100vh - 40px - 50px - 12px);
    }
  }
</style>
